package com.axzhengxin.platform.common.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.axzhengxin.platform.common.props.DataServiceAccount;
import com.axzhengxin.platform.common.service.IDataService;
import com.axzhengxin.platform.common.util.AesUtil;
import com.axzhengxin.platform.common.util.HttpClientUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.uuid.UUID;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * IDataServiceImpl
 *
 * @author jiangnan
 * @date 2021/2/23
 */
@Slf4j
@Service
public class DataServiceImpl implements IDataService {

    private DataServiceAccount account;

    @Autowired
    public DataServiceImpl(DataServiceAccount account) {
        this.account = account;
    }

    @Override
    public String invoke(@NotNull String url, @NotNull String requestBody, @NotNull String interfaceNo, boolean isEncrypt) {
        JSONObject request = initRequest(interfaceNo, requestBody);
        String requestData = initRequestData(request, isEncrypt);
        return Optional.ofNullable(execInvoke(url, requestData))
                .map(responseData -> parseResponseData(responseData, isEncrypt))
                .orElseThrow(() -> new RuntimeException("请求工商数据服务过程中发生异常"));
    }

    @Override
    public String invokeLegacy(String url, String requestData, boolean isEncrypt) {
        return null;
    }

    private JSONObject initRequest(String interfaceNo, String requestBody) {
        JSONObject request = new JSONObject();
        request.put("header", initRequestHeader(interfaceNo));
        request.put("body", JSON.parseObject(requestBody));
        return request;
    }

    private JSONObject initRequestHeader(String interfaceNo) {
        JSONObject header = JSON.parseObject(JSON.toJSONString(account));
        header.remove("aesKey");
        header.remove("afemarkId");
        header.put("interfaceNo", interfaceNo);
        header.put("reqSerialNo", UUID.fastUUID().toString(true));
        header.put("tradeDate", DateUtils.dateTimeNow("yyyyMMdd"));
        return header;
    }

    private String initRequestData(JSONObject request, boolean isEncrypt) {
        String requestJson;
        if (isEncrypt) {
            String aesKey = account.getAesKey();
            log.info(String.format("明文请求报文:%s", request.toJSONString()));
            requestJson = AesUtil.encryptToBase64String(request.toJSONString(), aesKey);
            log.info(String.format("密文请求报文:%s", requestJson));
        } else {
            requestJson = request.toJSONString();
            log.info(String.format("明文请求报文:%s", requestJson));
        }
        return requestJson;
    }

    @SneakyThrows
    private String execInvoke(String url, String requestData) {
        Map<String, String> headers = new HashMap<>(16);
        headers.put("afemarkId", account.getAfemarkId());
        return HttpClientUtil.post(url, requestData, headers, MediaType.APPLICATION_JSON_VALUE);
    }

    private String parseResponseData(String rawResponseData, boolean isEncrypt) {
        String responseData;
        if (isEncrypt) {
            String aesKey = account.getAesKey();
            log.info("密文响应报文:{}", rawResponseData);
            responseData = AesUtil.decryptFromBase64String(rawResponseData, aesKey);
            log.info("明文响应报文:{}", responseData);
        } else {
            responseData = rawResponseData;
            log.info("明文响应报文:{}", responseData);
        }
        return responseData;
    }

}
